package nrpc.client.slst;

import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import nrpc.client.serst.ConfiguredServiceStrategy;
import nrpc.client.serst.ServiceNode;
import nrpc.client.serst.ServiceStrategy;

public class PollingSelectStrategy implements SelectStrategy {

//	private final static long TIMEOUT = 10000;
	
	private ServiceStrategy serviceStrategy;
	private List<ServiceNode> nodes = new ArrayList<>();
	private volatile int i;
	
	public PollingSelectStrategy(InetSocketAddress address) {
		this(new ConfiguredServiceStrategy(address));
	}
	
	public PollingSelectStrategy(ServiceStrategy serviceStrategy) {
		this.serviceStrategy = serviceStrategy;
		this.serviceStrategy.subscribe(
				(addedNode)->{
					synchronized(this){
						nodes.add(addedNode);
						this.notifyAll();
					}
				}, 	
				(deletedNode)->{
					synchronized(this){
						nodes.remove(deletedNode);
					}
				});
//		this.socketWrapper = socketStrategy.getSocketWrappers().get(0);
	}

	@Override
	public Iterator<ServiceNode> getNode(Method method, List<Object> args) {
		return new Iterator<ServiceNode>(){
			@Override
			public boolean hasNext() {
				return nodes.size() > 0;
			}
			@Override
			public ServiceNode next() {
				if(i >= nodes.size()) i = 0;
				return nodes.get(i++);
			}
			@Override
			public void remove() {
				nodes.remove(--i);
			}
		};
	}

	@Override
	public synchronized void deleteNode(ServiceNode node) {
		nodes.remove(node);
	}
	
	@Override
	public void close() {
		this.serviceStrategy.close();
	}

//	@Override
//	public void deactivate(SocketChannel channel) {
//		this.socketWrapper.backSocketChannel(channel);
//	}


//	@Override
//	protected synchronized Iterator<? extends ServiceNode> getServiceQueue() {
//		while(nodes.size() == 0)
//			try {
//				this.wait(TIMEOUT);
//			} catch (InterruptedException e) {}
//		return new Iterator<ServiceNode>(){
//			@Override
//			public boolean hasNext() {
//				return nodes.size() > 0;
//			}
//			@Override
//			public ServiceNode next() {
//				if(i >= nodes.size()) i = 0;
//				return nodes.get(i++);
//			}
//			@Override
//			public void remove() {
//				nodes.remove(--i);
//			}
//		};
//	}

	
//	@Override
//	public synchronized void activateChannel(Method method, List<Object> args,
//			Function<? super SocketChannel, ? extends Boolean> active) {
//		long beg = System.currentTimeMillis();
//		super.activateChannel(method, args, active);
//		long time = System.currentTimeMillis() - beg;
//	}
	
}
